package dk.dtu.android.gui;

import java.util.List;

import dk.dtu.android.rejseplanen.Leg;
import dk.dtu.android.rejseplanen.Rejseplanen;
import dk.dtu.android.rejseplanen.StopLocation;
import dk.dtu.android.transport.R;
import dk.dtu.android.transport.TransportAPI;
import dk.dtu.android.transport.db.StopstationTable;
import dk.dtu.android.transport.gps.MyLocationListener;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class TInfoActivity extends Activity {

	AutoCompleteTextView src;
	AutoCompleteTextView dst;
    Button search;
    Button btnClear;
    
    TextView txtTrip;
    ListView listTrip;
    
    ArrayList<String> arrListTrip = new ArrayList<String>();
    ArrayAdapter<String> adapterTrip;
    
    ArrayList<String> arrStopstations = new ArrayList<String>();
    ArrayAdapter<String> adapterAuto;
    
    int srcSelected = 0;
    int dstSelected = 0;
    int tripSelected = 0;
    
    List<NameValuePair> params = new LinkedList<NameValuePair>();
    List<NameValuePair> params2 = new LinkedList<NameValuePair>();
    
    ArrayList<StopLocation> Loc;
    ArrayList<ArrayList<Leg>> trip;
    ArrayList<ArrayList<Leg>> leg;
    
    String srcName = "";
    String dstName = "";
    
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.tab_tinfo);
        
        src = (AutoCompleteTextView) findViewById(R.id.editText1);
        dst = (AutoCompleteTextView) findViewById(R.id.editText2);
        search = (Button) findViewById(R.id.button1);
        btnClear = (Button) findViewById(R.id.btnClear);
        
        txtTrip = (TextView) findViewById(R.id.textTrip);
        listTrip = (ListView) findViewById(R.id.listTrip);
        
        adapterTrip = new ArrayAdapter<String>(this, R.layout.list_item, arrListTrip);
        listTrip.setAdapter(adapterTrip);
        
        arrStopstations = StopstationTable.getStopstations();
        adapterAuto = new ArrayAdapter<String>(this, R.layout.list_item, arrStopstations);
        
        src.setAdapter(adapterAuto);
        dst.setAdapter(adapterAuto);
        
        listTrip.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> a, View v, int pos,
					long id) {
				nextState(pos);
				/*if(srcSelected == 0) {
					txtTrip.setText("Select a destination: ");
					srcName = Loc.get(pos).name;
					params2.add(new BasicNameValuePair("originId", Loc.get(pos).id));
					params2.add(new BasicNameValuePair("originCoordX", Loc.get(pos).x));
					params2.add(new BasicNameValuePair("originCoordy", Loc.get(pos).y));
					Loc.clear();
					srcSelected = 1;
					
					location(dst.getText().toString());
				}
				else if(dstSelected == 0) {
					txtTrip.setText("Select a trip: ");
					dstName = Loc.get(pos).name;
					params2.add(new BasicNameValuePair("destCoordX", Loc.get(pos).x));
					params2.add(new BasicNameValuePair("destCoordY", Loc.get(pos).y));
					params2.add(new BasicNameValuePair("destCoordName", Loc.get(pos).name));
					Loc.clear();
					dstSelected = 1;
					
					trip = trip(params2);
					Log.d("TInfoActivity", "Trip: " + trip);

				}
				else if((srcSelected == 1) && (dstSelected == 1)) {
					txtTrip.setText("Follow the instructions to get to your destination: ");
					Log.d("TInfoActivity", "Trip: " + trip);
					leg(trip.get(pos));
					trip.clear();
					tripSelected = 1;
				}*/
			}
        	
        });
        
        search.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {				
				srcSelected = 0;
				dstSelected = 0;
				tripSelected = 0;
				InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
				imm.hideSoftInputFromWindow(src.getWindowToken(), 0);
				nextState(null);
			}
        });
        
        btnClear.setOnClickListener(new OnClickListener() {
        	@Override
        	public void onClick(View v){
        		src.setText("");
        		dst.setText("");
        		arrListTrip.clear();
        		adapterTrip.notifyDataSetChanged();
        		txtTrip.setText("");
        	}
        });
        nextState(null);
    }
	
	public void nextState(Integer pos)
	{
		if(srcSelected == 0) {
			if (pos == null)
			{
				txtTrip.setText("Select a source: ");
				StopLocation loc;
				if(src.getText().toString().equals("Current Location") || src.getText().toString().equals(""))
				{
					loc = autoSelectFromCoord(MyLocationListener.x, MyLocationListener.y);
					if (loc == null)
					{
						// Select a stop nearby ...
						txtTrip.setText("Select a source: ");
					}
					else
					{
						src.setText(loc.name);
						srcName = loc.name;
						params2.add(new BasicNameValuePair("originId", loc.id));
						params2.add(new BasicNameValuePair("originCoordX", loc.x));
						params2.add(new BasicNameValuePair("originCoordy", loc.y));
						StopstationTable.insertIfNotExists(loc.id, loc.name, loc.x, loc.y);
						srcSelected = 1;
						nextState(null);
					}
				}
				else
				{
					location(src.getText().toString());
				}
			}
			else 
			{
				srcName = Loc.get(pos).name;
				src.setText(Loc.get(pos).name);
				params2.add(new BasicNameValuePair("originId", Loc.get(pos).id));
				params2.add(new BasicNameValuePair("originCoordX", Loc.get(pos).x));
				params2.add(new BasicNameValuePair("originCoordy", Loc.get(pos).y));
				StopstationTable.insertIfNotExists(Loc.get(pos).id, Loc.get(pos).name, Loc.get(pos).x, Loc.get(pos).y);
				Loc.clear();
				srcSelected = 1;
				
				nextState(null);
			}
		}
		else if(dstSelected == 0) {
			txtTrip.setText("Select a destination: ");
			if (pos == null)
			{
				if (dst.getText().toString().equals(""))
				{
					// Try to predict
					JSONObject result = TransportAPI.getPrediction(
						MyLocationListener.x, 
						MyLocationListener.y, 
						new Date()
					);
					if (result == null)
					{
						// Stop, no prediction, user must fill dst
						txtTrip.setText("You need to provide destination!");
					}
					else
					{
						StopLocation loc;
						try {
							loc = autoSelectFromCoord(result.getString("x"), result.getString("y"));
						} catch (JSONException e) {
							loc = null;
							e.printStackTrace();
						}
						if (loc == null)
						{
							// User must select from list
						}
						else
						{
							dst.setText(loc.name);
							dstName = loc.name;
							params2.add(new BasicNameValuePair("destCoordX", loc.x));
							params2.add(new BasicNameValuePair("destCoordY", loc.y));
							params2.add(new BasicNameValuePair("destCoordName", loc.name));
							StopstationTable.insertIfNotExists(loc.id, loc.name, loc.x, loc.y);
							dstSelected = 1;
							
							trip = trip(params2);
							Log.d("TInfoActivity", "Trip: " + trip);
							nextState(null);
						}
					}
				}
				else
				{
					location(dst.getText().toString());
				}
			}
			else
			{
				dstName = Loc.get(pos).name;
				dst.setText(dstName);
				params2.add(new BasicNameValuePair("destCoordX", Loc.get(pos).x));
				params2.add(new BasicNameValuePair("destCoordY", Loc.get(pos).y));
				params2.add(new BasicNameValuePair("destCoordName", Loc.get(pos).name));
				StopstationTable.insertIfNotExists(Loc.get(pos).id, Loc.get(pos).name, Loc.get(pos).x, Loc.get(pos).y);
				Loc.clear();
				dstSelected = 1;
				Log.d("TInfoActivity", "Trip: " + trip);
				nextState(null);
			}
		}
		else if((srcSelected == 1) && (dstSelected == 1) && tripSelected == 0) {
			txtTrip.setText("Select a trip: ");
			tripSelected = 1;
			trip = trip(params2);
		}
		else if((srcSelected == 1) && (dstSelected == 1) && tripSelected == 1) {
			txtTrip.setText("Follow the instructions to get to your destination: ");
			Log.d("TInfoActivity", "Trip: " + trip);
			leg(trip.get(pos));
			trip.clear();
			tripSelected = 1;
		}
	}

	public void stopsNearby(String x, String y) {
		params.clear();
		arrListTrip.clear();
		params.add(new BasicNameValuePair("coordX", x));
		params.add(new BasicNameValuePair("coordY", y));
		params.add(new BasicNameValuePair("maxRadius", "2000"));
		
        Loc = Rejseplanen.stopsNearby(params);
        
        for (int i = 0; i < Loc.size(); i++)
        	arrListTrip.add(Loc.get(i).name);
        
        adapterTrip.notifyDataSetChanged();
	}

	public void location(String input) {
		arrListTrip.clear();
		
		Loc = Rejseplanen.location(input);
		
		for (int i = 0; i < Loc.size(); i++) {
			Log.d("TInfoActivity", "Location ID: " + Loc.get(i).id);
			if (!Loc.get(i).id.equals(""))
				arrListTrip.add(Loc.get(i).name);
		}
		adapterTrip.notifyDataSetChanged();
	}
	
	public ArrayList<ArrayList<Leg>> trip(List<NameValuePair> par) {
		ArrayList<ArrayList<Leg>> tripTMP = Rejseplanen.trip(par);
		arrListTrip.clear();
		
		for (int i = 0; i < tripTMP.size(); i++) {
			arrListTrip.add("Trip " + Integer.toString(i+1) + ": "
					+ "From: " + srcName + "\nTo: " + dstName);
		}
		adapterTrip.notifyDataSetChanged();
		
		return tripTMP;
	}
	
	public void leg(ArrayList<Leg> leg) {
		arrListTrip.clear();
		String tmpString = "";
		for (int i = 0; i < leg.size(); i++) {
			String stringLeg = parseLeg(leg.get(i));
			Log.d("TInfoActivity", "Leg name: " + leg.get(i).legName);
			Log.d("TInfoActivity", "stringLeg: " + stringLeg);
			Log.d("TInfoActivity", "tmpString: " + tmpString);
			if (!stringLeg.equals(tmpString)) {
				Log.d("TInfoActivity", "Entering if statement");
				arrListTrip.add(stringLeg);
			}
			tmpString = stringLeg;
		}
		adapterTrip.notifyDataSetChanged();
	}
	
	public String parseLeg(Leg leg) {
		String legString = "";
		
		if (leg.legType.equals("WALK")) {
			legString = "Walk from " + leg.Orig.OrigDestName + " to " + leg.Dest.OrigDestName 
						+ " arrive at " + leg.Dest.OrigDestTime;
		}
		
		if(leg.legType.equals("BUS") || leg.legType.equals("EXB")) {
			legString = "Take the " + leg.legName + " from " + leg.Orig.OrigDestName
						+ " to " + leg.Dest.OrigDestName + " at " + leg.Orig.OrigDestTime;
		}
		
		if(leg.legType.equals("S")) {
			legString = "Take the " + leg.legName + " train from " + leg.Orig.OrigDestName
						+ " to " + leg.Dest.OrigDestName;
		}
		
		return legString;
	}
	
	public StopLocation autoSelectFromCoord(String x, String y)
	{
		params.clear();
		arrListTrip.clear();
		params.add(new BasicNameValuePair("coordX", x));
		params.add(new BasicNameValuePair("coordY", y));
		params.add(new BasicNameValuePair("maxRadius", "2000"));
		
		ArrayList<String> ids = new ArrayList<String>(); 
        Loc = Rejseplanen.stopsNearby(params);
        for (int i = 0; i < Loc.size(); i++)
        {
        	ids.add(Loc.get(i).id);
        }
        StopLocation loc = StopstationTable.getMostFrequent(ids);
        if (loc == null)
        {
            for (int i = 0; i < Loc.size(); i++)
            	arrListTrip.add(Loc.get(i).name);
            
            adapterTrip.notifyDataSetChanged();
            return null;
        }
        else
        {
        	return loc;
        }
        
	}
}
